package com.bocloud.cmp.service.app.resource;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bocloud.cmp.dao.app.ApplicationDao;
import com.bocloud.cmp.dao.app.ApplicationLayoutInfoDao;
import com.bocloud.cmp.dao.app.ApplicationOpenshiftClusterInfoDao;
import com.bocloud.cmp.dao.app.ApplicationSoftwareInfoDao;
import com.bocloud.cmp.dao.app.DeployHistoryDao;
import com.bocloud.cmp.dao.app.LayoutDao;
import com.bocloud.cmp.dao.app.OpenshiftClusterDao;
import com.bocloud.cmp.dao.app.RegistryDao;
import com.bocloud.cmp.dao.app.RegistryImageInfoDao;
import com.bocloud.cmp.dao.app.RegistrySoftwareDao;
import com.bocloud.cmp.dao.app.SoftwareDao;
import com.bocloud.cmp.entity.app.resource.Application;
import com.bocloud.cmp.entity.app.resource.ApplicationOpenshiftClusterInfo;
import com.bocloud.cmp.entity.app.resource.ApplicationSoftwareInfo;
import com.bocloud.cmp.entity.app.resource.Layout;
import com.bocloud.cmp.entity.app.resource.OpenshiftCluster;
import com.bocloud.cmp.entity.app.resource.Registry;
import com.bocloud.cmp.entity.app.resource.RegistryImageInfo;
import com.bocloud.cmp.entity.app.resource.Software;
import com.bocloud.cmp.service.utils.OpenshiftUtil;
import com.bocloud.cmp.service.utils.ResourceEventPublisher;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.utils.IDFactory;
import com.bocloud.log.dao.LogDao;
import com.bocloud.log.entity.AccessLog;
import com.bocloud.soc.dao.intf.AuthDao;
import com.bocloud.soc.dao.intf.DepartmentDao;
import com.bocloud.soc.dao.intf.RoleDao;
import com.bocloud.soc.dao.intf.UserDao;
import com.bocloud.soc.entity.Authority;
import com.bocloud.soc.entity.Role;
import com.bocloud.soc.entity.User;
import com.bocloud.soc.interfaces.UserService;

/**
 * 公用service
 * 
 * @author zjm
 *
 */
@Service("commonService")
public class CommonServiceImpl {

	private static Logger logger = LoggerFactory.getLogger(CommonServiceImpl.class);

	@Autowired
	protected LogDao logDao;
	@Autowired
	protected RegistryDao registryDao;
	@Autowired
	protected UserDao userDao;
	@Autowired
	protected RegistryImageInfoDao registryImageInfoDao;
	@Autowired
	protected RegistrySoftwareDao registrySoftwareDao;
	@Autowired
	protected SoftwareDao softwareDao;
	@Autowired
	protected UserService userService;
	@Autowired
	protected AuthDao authDao;
	@Autowired
	protected RoleDao roleDao;
	@Autowired
	protected ApplicationDao applicationDao;
	@Autowired
	protected LayoutDao layoutDao;
	@Autowired
	protected ApplicationLayoutInfoDao applicationLayoutInfoDao;
	@Autowired
	protected ApplicationSoftwareInfoDao applicationSoftwareInfoDao;
	@Autowired
	protected ApplicationOpenshiftClusterInfoDao applicationOpenshiftClusterInfoDao;
	@Autowired
	protected OpenshiftUtil oseUtil;
	@Autowired
	protected DeployHistoryDao deployHistoryDao;
	@Autowired
	protected ResourceEventPublisher resourceEventPublisher;
	@Autowired
	protected OpenshiftClusterDao openshiftClusterDao;
	@Autowired
	DepartmentDao departmentDao;

	protected BsmResult saveLog(String object, String action, String result, Long userId) {
		AccessLog accessLog = new AccessLog();
		accessLog.setId(IDFactory.instance().uuid());
		accessLog.setAction(action);
		accessLog.setResult(result);
		accessLog.setUserId(userId);
		accessLog.setObject(object);
		accessLog.setModule("CMP.API");
		accessLog.setGmtCreate(new Date());
		try {
			logDao.save(accessLog);
		} catch (Exception e) {
			logger.error("save access log failure: ", e);
			return new BsmResult(false, "添加操作记录成功！" + e);
		}
		return new BsmResult(true, "添加操作记录成功！");
	}

	protected Registry queryRegistry(Long registryId, BsmResult bsmResult) {
		// 获取仓库信息
		Registry registry = null;
		try {
			registry = registryDao.query(registryId);
		} catch (Exception e) {
			logger.error("query registry [" + registryId + "] failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取仓库[" + registryId + "]信息失败！");
		}
		if (null == registry) {
			logger.warn("query registry [" + registryId + "] empty.");
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取仓库[" + registryId + "]信息为空！");
		}
		return registry;
	}

	protected User queryUser(Long userId, BsmResult bsmResult) {
		User user = null;
		try {
			user = userDao.query(userId);
		} catch (Exception e) {
			logger.error("query user [" + userId + "] failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取用户[" + userId + "]信息失败！");
		}
		if (null == user) {
			logger.warn("query user [" + userId + "] empty.");
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取用户[" + userId + "]信息为空！");
		}
		return user;
	}

	protected Application queryApplication(Long appId, BsmResult bsmResult) {
		Application application = null;
		try {
			application = applicationDao.query(appId);
		} catch (Exception e) {
			logger.error("query application [" + appId + "] failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取应用[" + appId + "]信息失败！");
		}
		if (null == application) {
			logger.warn("query application [" + appId + "] empty.");
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取应用[" + appId + "]信息为空！");
		}
		return application;
	}
 
	protected OpenshiftCluster queryOpenshiftCluster(Long clusterId, BsmResult bsmResult) {
		OpenshiftCluster openshiftCluster = null;
		try {
			openshiftCluster = openshiftClusterDao.query(clusterId);
		} catch (Exception e) {
			logger.error("query cluster [" + clusterId + "] failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取集群[" + clusterId + "]信息失败！");
		}
		if (null == openshiftCluster) {
			logger.warn("query cluster [" + clusterId + "] empty.");
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取集群[" + clusterId + "]信息为空！");
		}
		return openshiftCluster;
	}

	protected Software querySoftware(Long softwareId, BsmResult bsmResult) {
		Software software = null;
		try {
			software = softwareDao.query(softwareId);
		} catch (Exception e) {
			logger.error("query software [" + softwareId + "] failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取镜像[" + softwareId + "]信息失败！");
		}
		if (null == software) {
			logger.warn("query software [" + softwareId + "] empty.");
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取镜像[" + softwareId + "]信息为空！");
		}
		return software;
	}

	protected Layout queryLayout(Long layoutId, BsmResult bsmResult) {
		Layout layout = null;
		try {
			layout = layoutDao.query(layoutId);
		} catch (Exception e) {
			logger.error("query layout [" + layoutId + "] failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取编排文件[" + layoutId + "]信息失败！");
		}
		if (null == layout || StringUtils.isAnyBlank(layout.getFilePath(), layout.getFileName())) {
			logger.warn("query layout [" + layoutId + "] empty.");
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取编排文件信息为空！");
		}
		return layout;
	}

	protected ApplicationOpenshiftClusterInfo queryApplicationOpenshiftClusterInfo(Long appId, BsmResult bsmResult) {
		ApplicationOpenshiftClusterInfo applicationOpenshiftClusterInfo = null;
		try {
			applicationOpenshiftClusterInfo = applicationOpenshiftClusterInfoDao
					.getApplicationOpenshiftClusterInfo(appId);
		} catch (Exception e) {
			logger.error("query application [" + appId + "] cluster middle table failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取应用[" + appId + "]集群中间表信息失败！");
		}
		if (null == applicationOpenshiftClusterInfo) {
			logger.warn("query application [" + appId + "] cluster middle table empty.");
			bsmResult.setMessage("获取应用[" + appId + "]集群中间表信息为空！");
		}
		return applicationOpenshiftClusterInfo;
	}

	protected RegistryImageInfo queryRegistryImageInfo(Long imageId, BsmResult bsmResult) {
		// 获取仓库镜像中间表信息
		RegistryImageInfo registryImageInfo = null;
		try {
			registryImageInfo = registryImageInfoDao.getByImageId(imageId);
		} catch (Exception e) {
			logger.error("query registry image middle table [" + imageId + "] failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取仓库镜像[" + imageId + "]信息失败！");
		}
		if (null == registryImageInfo) {
			logger.warn("query registry image middle table [" + imageId + "] empty.");
			bsmResult.setMessage("获取仓库镜像[" + imageId + "]信息为空！");
		}
		return registryImageInfo;
	}
	
	protected ApplicationSoftwareInfo queryApplicationSoftwareByAppIdAndSoftwareId(Long appId, Long softwareId,
			BsmResult bsmResult) {
		ApplicationSoftwareInfo applicationSoftwareInfo = null;
		try {
			applicationSoftwareInfo = applicationSoftwareInfoDao.getByAppIdAndSoftwareId(appId, softwareId);
		} catch (Exception e) {
			logger.error("query application [" + appId + "] software [" + softwareId + "] middle table failure: ", e);
			bsmResult.setSuccess(false);
			bsmResult.setMessage("获取应用[" + appId + "]镜像[" + softwareId + "]中间表失败！");
		}
		if (null == applicationSoftwareInfo) {
			logger.warn("query application [" + appId + "] software [" + softwareId + "] middle table empty.");
			bsmResult.setMessage("获取应用[" + appId + "]镜像[" + softwareId + "]中间表为空！");
		}
		return applicationSoftwareInfo;
	}

	protected String queryUserDeptId(Long userId) throws Exception {
		String deptId = userService.listDept(userId);
		// 判断当前用户是否拥有查看“容器平台”的权限，如果有则可以查看所有的镜像
		User user = null;
		if (null == (user = queryUser(userId, new BsmResult()))) {
			return null;
		}
		List<Role> roles = roleDao.listByUid(user.getId());
		for (Role role : roles) {
			List<Authority> authorities = authDao.listByRid(role.getId());
			for (Authority authority : authorities) {
				// TODO 和威哥少龙沟通后暂时写死判断“容器平台”权限的id
				// 具有“容器平台”的人具有“特殊”权限
				if (authority.getId().equals(new Long(132))) {
					deptId = null;
					break;
				}
			}
		}
		return deptId;
	}
	
	public String getImageByAppIdAndSoftwareId(Long appId, Long softwareId) {
		BsmResult bsmResult = new BsmResult();
		String image = "";
		try {
			ApplicationSoftwareInfo applicationSoftwareInfo = applicationSoftwareInfoDao.getByAppIdAndSoftwareId(appId,
					softwareId);
			Software software = querySoftware(applicationSoftwareInfo.getSoftwareId(), bsmResult);
			if (null != software) {
				RegistryImageInfo registryImageInfo = queryRegistryImageInfo(software.getId(), bsmResult);
				if (null != registryImageInfo) {
					Registry registry = queryRegistry(registryImageInfo.getRepositoryId(), bsmResult);
					if (null != registry) {
						image = registry.getAddress();
						if (null != registry.getRegistryPort()) {
							image += ":" + registry.getRegistryPort();
						}
						image += "/";
						if (StringUtils.isNotBlank(registryImageInfo.getNamespace())) {
							image += registryImageInfo.getNamespace() + "/";
						}
						image += software.getName();
						if (StringUtils.isNotBlank(software.getVersion())) {
							image += ":" + software.getVersion();
						}
					}
				}
			}
		} catch (Exception e) {
			logger.error("获取镜像信息失败：\n", e);
			return image;
		}
		return image;
	}
}
